Pressidian
花园入口
笔记
项目
关于
实验室
GitHub
花园入口
笔记
项目
关于
实验室
GitHub

KNOWLEDGE PATHS

笔记库
当前位置
笔记库/前端/面试/八股/TS

any、unknown 和 never

3 分钟阅读 · Note

目录树 578 篇

            • any、unknown 和 never
            • as const
            • First
          • 进阶篇题目列表
          • DOM&浏览器 API
          • HTTP&网络
          • TS
          • Vue
        • 可投递企业
      • 前端技术栈
    • 笔记目录
    • CLAUDE.md
    • Vue 组件与 Render 函数

关联笔记 6

↗as const同一路径↗First同一路径↗1基础篇共同主题↗2进阶篇共同主题↗4手写篇共同主题↗5AI面试共同主题

在 TypeScript 中,any、unknown 和 never 是三个非常特殊且核心的类型。它们在类型系统中的定位截然不同:any 和 unknown 属于顶层类型(Top Type),而 never 是唯一的底层类型(Bottom Type)。

以下是它们的关系与核心区别的详细解析:

1. 核心特性对比速查表

特性anyunknownnever
类型安全性❌ 无检查(完全禁用)✅ 安全(需类型检查后才能操作)✅ 最高安全性(不可操作)
赋值能力可接受任意值,也可赋给任意类型可接受任意值,但只能赋给 any 或 unknown不能接受任何值,但可赋给任意类型
操作自由度可随意调用属性/方法(编译不报错)❌ 禁止直接操作(必须先进行类型收窄或断言)❌ 无法实例化或进行任何操作
设计目的兼容无类型的 JS 代码或快速迁移安全地处理不确定类型的动态数据表示永不存在的值,确保逻辑完备性

2. 详细解析与使用场景

🛑 any:灵活但危险的“万能类型”

  • 特点:当你声明一个变量为 any 时,TypeScript 会完全关闭对该变量的类型检查。你可以对它进行任何操作,甚至调用不存在的方法,编译器都不会报错,但这极易导致运行时错误。
  • 适用场景:仅在将现有的 JavaScript 代码迁移到 TypeScript 的过渡期,或者处理完全没有类型定义的第三方库时作为临时方案使用。
  • 风险:过度使用会削弱 TS 的类型检查优势,降低代码的可维护性和安全性。

🔒 unknown:安全的未知类型容器

  • 特点:它是 TypeScript 3.0 引入的严格版 any。虽然它可以接收任意类型的值,但在你通过类型守卫(如 typeof、instanceof)或类型断言(as)明确其具体类型之前,不允许对其进行任何操作,也不能将其赋值给其他非 any/unknown 类型的变量。
  • 适用场景:处理来自外部的不确定数据(如 API 响应、JSON.parse() 的结果、用户输入等),替代 any 以强制开发者显式处理类型,避免隐藏错误。

⛔ never:逻辑完备性的守护者

  • 特点:它表示那些永远不会存在的值。由于空集是任何集合的子集,never 是所有其他类型的子类型,因此它可以赋值给任何类型;但除了 never 自身,没有任何类型可以赋值给它(包括 any)。
  • 适用场景:
    1. 标记永不返回的函数:例如抛出异常的函数或陷入无限循环的死循环函数。
    2. 穷尽性检查(Exhaustiveness Checking):在处理联合类型的 switch/case 语句中,利用 never 确保所有可能的分支都被处理。如果后续新增了类型但忘记处理,编译器会在 default 分支报错。
    3. 高级类型编程:在条件类型中用于过滤无效值(如内置工具类型 Exclude<T, U>)。

3. 类型层次结构总结

从集合论的角度来理解它们的层级关系会更加直观:

  • unknown 是类型安全的顶层类型(全集)。
  • any 既是顶层也是底层类型,但它脱离了类型系统的约束。
  • never 是最底层的类型(空集),位于整个类型结构的最底部。
      unknown (顶层类型 / 全集)
         ↑
        any (破坏类型系统)
         ↑
   所有其他常规类型
         ↑
      never (底层类型 / 空集)

最佳实践建议:在日常开发中,应遵循 unknown > never > any 的优先级策略。优先使用 unknown 处理动态数据,善用 never 保证逻辑分支完备,而将 any 仅作为最后的应急手段。


需要我通过代码示例,帮你进一步理解它们的赋值规则和类型收窄机制吗?